// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Requests;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;
using Elastic.Transport.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Security;

public sealed partial class GrantApiKeyRequestParameters : RequestParameters
{
}

/// <summary>
/// <para>
/// Creates an API key on behalf of another user.
/// This API is similar to Create API keys, however it creates the API key for a user that is different than the user that runs the API.
/// The caller must have authentication credentials (either an access token, or a username and password) for the user on whose behalf the API key will be created.
/// It is not possible to use this API to create an API key without that user’s credentials.
/// The user, for whom the authentication credentials is provided, can optionally "run as" (impersonate) another user.
/// In this case, the API key will be created on behalf of the impersonated user.
/// </para>
/// <para>
/// This API is intended be used by applications that need to create and manage API keys for end users, but cannot guarantee that those users have permission to create API keys on their own behalf.
/// </para>
/// <para>
/// A successful grant API key API call returns a JSON structure that contains the API key, its unique id, and its name.
/// If applicable, it also returns expiration information for the API key in milliseconds.
/// </para>
/// <para>
/// By default, API keys never expire. You can specify expiration information when you create the API keys.
/// </para>
/// </summary>
public sealed partial class GrantApiKeyRequest : PlainRequest<GrantApiKeyRequestParameters>
{
	internal override ApiUrls ApiUrls => ApiUrlLookup.SecurityGrantApiKey;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "security.grant_api_key";

	/// <summary>
	/// <para>
	/// The user’s access token.
	/// If you specify the <c>access_token</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("access_token")]
	public string? AccessToken { get; set; }

	/// <summary>
	/// <para>
	/// Defines the API key.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("api_key")]
	public Elastic.Clients.Elasticsearch.Security.GrantApiKey ApiKey { get; set; }

	/// <summary>
	/// <para>
	/// The type of grant. Supported grant types are: <c>access_token</c>, <c>password</c>.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("grant_type")]
	public Elastic.Clients.Elasticsearch.Security.ApiKeyGrantType GrantType { get; set; }

	/// <summary>
	/// <para>
	/// The user’s password. If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("password")]
	public string? Password { get; set; }

	/// <summary>
	/// <para>
	/// The name of the user to be impersonated.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("run_as")]
	public Elastic.Clients.Elasticsearch.Username? RunAs { get; set; }

	/// <summary>
	/// <para>
	/// The user name that identifies the user.
	/// If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("username")]
	public Elastic.Clients.Elasticsearch.Username? Username { get; set; }
}

/// <summary>
/// <para>
/// Creates an API key on behalf of another user.
/// This API is similar to Create API keys, however it creates the API key for a user that is different than the user that runs the API.
/// The caller must have authentication credentials (either an access token, or a username and password) for the user on whose behalf the API key will be created.
/// It is not possible to use this API to create an API key without that user’s credentials.
/// The user, for whom the authentication credentials is provided, can optionally "run as" (impersonate) another user.
/// In this case, the API key will be created on behalf of the impersonated user.
/// </para>
/// <para>
/// This API is intended be used by applications that need to create and manage API keys for end users, but cannot guarantee that those users have permission to create API keys on their own behalf.
/// </para>
/// <para>
/// A successful grant API key API call returns a JSON structure that contains the API key, its unique id, and its name.
/// If applicable, it also returns expiration information for the API key in milliseconds.
/// </para>
/// <para>
/// By default, API keys never expire. You can specify expiration information when you create the API keys.
/// </para>
/// </summary>
public sealed partial class GrantApiKeyRequestDescriptor<TDocument> : RequestDescriptor<GrantApiKeyRequestDescriptor<TDocument>, GrantApiKeyRequestParameters>
{
	internal GrantApiKeyRequestDescriptor(Action<GrantApiKeyRequestDescriptor<TDocument>> configure) => configure.Invoke(this);

	public GrantApiKeyRequestDescriptor()
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.SecurityGrantApiKey;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "security.grant_api_key";

	private string? AccessTokenValue { get; set; }
	private Elastic.Clients.Elasticsearch.Security.GrantApiKey ApiKeyValue { get; set; }
	private Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor<TDocument> ApiKeyDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor<TDocument>> ApiKeyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Security.ApiKeyGrantType GrantTypeValue { get; set; }
	private string? PasswordValue { get; set; }
	private Elastic.Clients.Elasticsearch.Username? RunAsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Username? UsernameValue { get; set; }

	/// <summary>
	/// <para>
	/// The user’s access token.
	/// If you specify the <c>access_token</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> AccessToken(string? accessToken)
	{
		AccessTokenValue = accessToken;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines the API key.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> ApiKey(Elastic.Clients.Elasticsearch.Security.GrantApiKey apiKey)
	{
		ApiKeyDescriptor = null;
		ApiKeyDescriptorAction = null;
		ApiKeyValue = apiKey;
		return Self;
	}

	public GrantApiKeyRequestDescriptor<TDocument> ApiKey(Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor<TDocument> descriptor)
	{
		ApiKeyValue = null;
		ApiKeyDescriptorAction = null;
		ApiKeyDescriptor = descriptor;
		return Self;
	}

	public GrantApiKeyRequestDescriptor<TDocument> ApiKey(Action<Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor<TDocument>> configure)
	{
		ApiKeyValue = null;
		ApiKeyDescriptor = null;
		ApiKeyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The type of grant. Supported grant types are: <c>access_token</c>, <c>password</c>.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> GrantType(Elastic.Clients.Elasticsearch.Security.ApiKeyGrantType grantType)
	{
		GrantTypeValue = grantType;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The user’s password. If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> Password(string? password)
	{
		PasswordValue = password;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The name of the user to be impersonated.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> RunAs(Elastic.Clients.Elasticsearch.Username? runAs)
	{
		RunAsValue = runAs;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The user name that identifies the user.
	/// If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor<TDocument> Username(Elastic.Clients.Elasticsearch.Username? username)
	{
		UsernameValue = username;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AccessTokenValue))
		{
			writer.WritePropertyName("access_token");
			writer.WriteStringValue(AccessTokenValue);
		}

		if (ApiKeyDescriptor is not null)
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, ApiKeyDescriptor, options);
		}
		else if (ApiKeyDescriptorAction is not null)
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor<TDocument>(ApiKeyDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, ApiKeyValue, options);
		}

		writer.WritePropertyName("grant_type");
		JsonSerializer.Serialize(writer, GrantTypeValue, options);
		if (!string.IsNullOrEmpty(PasswordValue))
		{
			writer.WritePropertyName("password");
			writer.WriteStringValue(PasswordValue);
		}

		if (RunAsValue is not null)
		{
			writer.WritePropertyName("run_as");
			JsonSerializer.Serialize(writer, RunAsValue, options);
		}

		if (UsernameValue is not null)
		{
			writer.WritePropertyName("username");
			JsonSerializer.Serialize(writer, UsernameValue, options);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Creates an API key on behalf of another user.
/// This API is similar to Create API keys, however it creates the API key for a user that is different than the user that runs the API.
/// The caller must have authentication credentials (either an access token, or a username and password) for the user on whose behalf the API key will be created.
/// It is not possible to use this API to create an API key without that user’s credentials.
/// The user, for whom the authentication credentials is provided, can optionally "run as" (impersonate) another user.
/// In this case, the API key will be created on behalf of the impersonated user.
/// </para>
/// <para>
/// This API is intended be used by applications that need to create and manage API keys for end users, but cannot guarantee that those users have permission to create API keys on their own behalf.
/// </para>
/// <para>
/// A successful grant API key API call returns a JSON structure that contains the API key, its unique id, and its name.
/// If applicable, it also returns expiration information for the API key in milliseconds.
/// </para>
/// <para>
/// By default, API keys never expire. You can specify expiration information when you create the API keys.
/// </para>
/// </summary>
public sealed partial class GrantApiKeyRequestDescriptor : RequestDescriptor<GrantApiKeyRequestDescriptor, GrantApiKeyRequestParameters>
{
	internal GrantApiKeyRequestDescriptor(Action<GrantApiKeyRequestDescriptor> configure) => configure.Invoke(this);

	public GrantApiKeyRequestDescriptor()
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.SecurityGrantApiKey;

	protected override HttpMethod StaticHttpMethod => HttpMethod.POST;

	internal override bool SupportsBody => true;

	internal override string OperationName => "security.grant_api_key";

	private string? AccessTokenValue { get; set; }
	private Elastic.Clients.Elasticsearch.Security.GrantApiKey ApiKeyValue { get; set; }
	private Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor ApiKeyDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor> ApiKeyDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Security.ApiKeyGrantType GrantTypeValue { get; set; }
	private string? PasswordValue { get; set; }
	private Elastic.Clients.Elasticsearch.Username? RunAsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Username? UsernameValue { get; set; }

	/// <summary>
	/// <para>
	/// The user’s access token.
	/// If you specify the <c>access_token</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor AccessToken(string? accessToken)
	{
		AccessTokenValue = accessToken;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Defines the API key.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor ApiKey(Elastic.Clients.Elasticsearch.Security.GrantApiKey apiKey)
	{
		ApiKeyDescriptor = null;
		ApiKeyDescriptorAction = null;
		ApiKeyValue = apiKey;
		return Self;
	}

	public GrantApiKeyRequestDescriptor ApiKey(Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor descriptor)
	{
		ApiKeyValue = null;
		ApiKeyDescriptorAction = null;
		ApiKeyDescriptor = descriptor;
		return Self;
	}

	public GrantApiKeyRequestDescriptor ApiKey(Action<Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor> configure)
	{
		ApiKeyValue = null;
		ApiKeyDescriptor = null;
		ApiKeyDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The type of grant. Supported grant types are: <c>access_token</c>, <c>password</c>.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor GrantType(Elastic.Clients.Elasticsearch.Security.ApiKeyGrantType grantType)
	{
		GrantTypeValue = grantType;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The user’s password. If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor Password(string? password)
	{
		PasswordValue = password;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The name of the user to be impersonated.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor RunAs(Elastic.Clients.Elasticsearch.Username? runAs)
	{
		RunAsValue = runAs;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The user name that identifies the user.
	/// If you specify the <c>password</c> grant type, this parameter is required.
	/// It is not valid with other grant types.
	/// </para>
	/// </summary>
	public GrantApiKeyRequestDescriptor Username(Elastic.Clients.Elasticsearch.Username? username)
	{
		UsernameValue = username;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (!string.IsNullOrEmpty(AccessTokenValue))
		{
			writer.WritePropertyName("access_token");
			writer.WriteStringValue(AccessTokenValue);
		}

		if (ApiKeyDescriptor is not null)
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, ApiKeyDescriptor, options);
		}
		else if (ApiKeyDescriptorAction is not null)
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Security.GrantApiKeyDescriptor(ApiKeyDescriptorAction), options);
		}
		else
		{
			writer.WritePropertyName("api_key");
			JsonSerializer.Serialize(writer, ApiKeyValue, options);
		}

		writer.WritePropertyName("grant_type");
		JsonSerializer.Serialize(writer, GrantTypeValue, options);
		if (!string.IsNullOrEmpty(PasswordValue))
		{
			writer.WritePropertyName("password");
			writer.WriteStringValue(PasswordValue);
		}

		if (RunAsValue is not null)
		{
			writer.WritePropertyName("run_as");
			JsonSerializer.Serialize(writer, RunAsValue, options);
		}

		if (UsernameValue is not null)
		{
			writer.WritePropertyName("username");
			JsonSerializer.Serialize(writer, UsernameValue, options);
		}

		writer.WriteEndObject();
	}
}